/**
 * 
 */
package tilex.sim;

import java.awt.*;
import javax.swing.*;
import javax.swing.border.BevelBorder;

class SimPanel extends JPanel implements Runnable {

	private static final long	serialVersionUID	= -4364228656417686485L;
	private Field				field				= null;
	private Thread				simThread			= null;
	private int					updateDelay			= 10;
	private int					cellSize			= 8;
	private int					cellGap				= 1;
	private int					showNthStep			= 5;

	public void setUpdateDelay(int updateDelay) {
		this.updateDelay = updateDelay;
	}

	public void setFieldVisualProperties(int cellSize, int cellGap, int showNthStep) {
		this.cellSize = cellSize;
		this.cellGap = cellGap;
		this.showNthStep = showNthStep;
	}

	public SimPanel() {
		setBackground(new Color(0x606060));
		setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
//			setDoubleBuffered(false);
	}

	public Field getField() {
		return field;
	}

	public void initializeField(int width, int height, int resourceCount) {
		field = new Field(width, height, resourceCount);
	}

	public void startSimulation() {
		if (simThread == null) {
			simThread = new Thread(this);
			simThread.start();
		}
	}

	public void stopSimulation() {
		simThread = null;
	}

	@Override public void run() {
//		updateResourceCounters();
		repaint();
		int i = 0;
		while (simThread != null) {
			try {
				Thread.sleep(updateDelay);
			} catch (InterruptedException e) {}
			synchronized (field) {
				field.simulate();
			}
			if (i++ % showNthStep == 0) {
				repaint();
//				updateResourceCounters();
			}
		}
		repaint();
	}

	public boolean isSimulating() {
		return simThread != null;
	}

	@Override public Dimension getPreferredSize() {
		if (field != null) {
			Insets b = getInsets();
			return new Dimension((cellSize + cellGap) * field.getWidth() + cellGap + b.left + b.right,
							(cellSize + cellGap) * field.getHeight() + cellGap + b.top + b.bottom);
		} else
			return new Dimension(100, 100);
	}

	@Override protected void paintComponent(Graphics g) {
		super.paintComponent(g); // дефолтная реализация LaF очищает компонент цветом фона
		if (field != null) {
			// т.к. поле обрабатывается в отдельном потоке, может возникнуть ситуация, когда будет выводиться частично обработанное поле.
			// чтобы это исключить, будем использовать синхронизацию
			Insets b = getInsets();
			synchronized (field) {
				for (int y = 0; y < field.getHeight(); y++) {
					for (int x = 0; x < field.getWidth(); x++) {
						Creature c = field.getCreature(x, y);
						// пустую клетку показываем белым цветом
						int color = c == null ? 15 : c.getColor();
						g.setColor(Palette.getColor(color));
						g.fillRect(b.left + cellGap + x * (cellSize + cellGap), b.top + cellGap + y
										* (cellSize + cellGap), cellSize,
										cellSize);
					}
				}
			}
		}
	}

}
